﻿//======================================================================== 
//    Copyright (C) 2010-2012  GaoTime All rights reserved. 
//
//    CLR Version: 4.0.30319.261 
//    NameSpace: HQ.Business 
//    FileName: HQData 
// 
//    Created by GT-YONGZHENG-01\yongzheng 
//    Email:zhengyong145@163.com
//  ======================================================================

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Web;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.IO;

using KCurveAPI;
using GA.Utils;
using Dundas.Charting.WebControl;
using HQ.Model;
using HQ.Model.Charts;
 

namespace HQ.Business
{
    public class HQData
    {
        public const int MAX_LEN = 255;
        //protected GetStockQuote GetStockQuote;
        public KCurve KCurve ;
        public delegate void DrawHandler(string windcode);
        public static DrawHandler objDrawHandler;
        public static TradeTime TradeTime = new TradeTime();
        public static HQData Crurent =new HQData();
        public static Hashtable hashtable = new Hashtable();
        private static object sychronize = new object();

        public HQData()
        {
            //if (GetStockQuote != null)
            //{
            //    KCurve = new KCurve(GetStockQuote);
            //}
            //else 
            //{
                KCurve = new KCurve(GetStockQuoteDefault);
            //}
                objDrawHandler = new DrawHandler(DrawChart);

            Thread t = new Thread(new ThreadStart(Run));
            t.Start();
        }

        public static void Draw(string windcode)
        {
            if (objDrawHandler != null)
            {
                Thread t = new Thread(new ThreadStart(delegate() { objDrawHandler(windcode); }));
                t.Start();
            }
            //objDrawHandler(windcode);
            
        }

        void Run()
        {
            // 测试获取交易时间
            DateTime QuoteStartTime = ParseHelper.PareStrToDateTime("9:30", "H:mm");
            DateTime PauseStartTime = ParseHelper.PareStrToDateTime("11:30", "H:mm");
            DateTime PauseEndTime = ParseHelper.PareStrToDateTime("13:00", "H:mm");
            DateTime QuoteEndTime = ParseHelper.PareStrToDateTime("15:00", "H:mm");

            KCurve.GetQuoteTimeInfo(out QuoteStartTime, out PauseStartTime, out PauseEndTime, out QuoteEndTime);

            TradeTime.QuoteStartTime = QuoteStartTime;
            TradeTime.PauseStartTime = PauseStartTime;
            TradeTime.PauseEndTime = PauseEndTime;
            TradeTime.QuoteEndTime = QuoteEndTime;

            KCurve.work();
        }

       static int GetStockQuoteDefault(StockQuotePoint sq)
        {
            try
            {
                if (string.IsNullOrEmpty(sq.Windcode))
                {
                    return 0;
                }

                StockQuote refStockQuote;
                if (!hashtable.ContainsKey(sq.Windcode))
                {
                    refStockQuote = new StockQuote();
                    hashtable.Add(sq.Windcode, refStockQuote);
                }
                else if (hashtable[sq.Windcode] == null)
                {
                    refStockQuote = new StockQuote();
                    hashtable[sq.Windcode] = refStockQuote;
                }
                else
                {
                    refStockQuote = hashtable[sq.Windcode] as StockQuote;
                }

                refStockQuote.QuoteStartTime = TradeTime.QuoteStartTime;
                refStockQuote.QuoteEndTime = TradeTime.QuoteEndTime;
                refStockQuote.PauseStartTime = TradeTime.PauseStartTime;
                refStockQuote.PauseEndTime = TradeTime.PauseEndTime;

                //todo 在休市时间内，就不要加入到集合里面去了。
                if (!CheckIfInQuoteTime(refStockQuote, sq))
                {
                    return 0;
                }

                refStockQuote.Windcode = sq.Windcode;
                refStockQuote.ShortName = sq.ShortName;
                refStockQuote.CurrentDate = sq.CurrentDate;
                refStockQuote.CurrentPrice = ParseHelper.Parse<double>(sq.CurrentPrice).ToString("N2");
                refStockQuote.Swing = sq.Swing;
                refStockQuote.SwingPercent = ParseHelper.Parse<double>(sq.SwingPercent).ToString("P2");
                refStockQuote.IsDown = sq.IsDown;
                refStockQuote.YestodayPrice = ParseHelper.Parse<double>(sq.YestodayPrice);

                //即使在minute和second之间切换也可以
                if (!string.IsNullOrEmpty(sq.CurrentDate))
                {
                    var iLast = refStockQuote.QuoteDateList.Count - 1;
                    var last =refStockQuote.QuoteDateList.Count>0? refStockQuote.QuoteDateList.Last():null;
                    if (sq.CurrentDate == last)
                    {                        
                        //也存在同步问题，但是为了性能，先不处理
                        refStockQuote.QuotePriceList[iLast] = ParseHelper.Parse<double>(sq.CurrentPrice);
                        refStockQuote.QuoteSwingPercentList[iLast] = ParseHelper.Parse<double>(sq.SwingPercent);
                        //Draw(refStockQuote.Windcode);
                    }
                    else
                    {
                        //这里出现一个锁的问题，不锁就会出现针对同一对象，不同步                        
                        lock (refStockQuote)
                        {
                            refStockQuote.QuoteDateList.Add(sq.CurrentDate);
                            refStockQuote.QuotePriceList.Add(ParseHelper.Parse<double>(sq.CurrentPrice));
                            refStockQuote.QuoteSwingPercentList.Add(ParseHelper.Parse<double>(sq.SwingPercent));
                        }

                        Draw(refStockQuote.Windcode);
                    }
                }
                
            }
            catch (Exception e)
            {
                LogHelper.Write("FeedHandler 调用出错！",e);
            }            

            return 0;
        }

       /// <summary>
       /// 规定运行时间
       /// </summary>
       /// <param name="refStockQuote"></param>
       /// <param name="sq"></param>
       /// <returns></returns>
       static bool CheckIfInQuoteTime(StockQuote refStockQuote, StockQuotePoint sq)
       {
           bool flag = false;
           double preTime=-30;
           double postTime=30;
           var start=refStockQuote.QuoteStartTime.AddMinutes(preTime);
           var end=refStockQuote.QuoteEndTime.AddMinutes(postTime);
           var currentTime = ParseHelper.PareStrToDateTime(sq.CurrentDate);
           //规则
           if (currentTime >= start && currentTime<=refStockQuote.PauseStartTime)
           {
               flag = true;
           }

           if (currentTime >= refStockQuote.PauseEndTime && currentTime<=end)
           {
               flag = true;
           }

           return flag;
       }


        //--------------------------------------------------------
        //此方法没有了，
       void DrawCharts()
       {
           //hashtable肯定是不断变化的，这个时候，我就需要，心跳状态  做copy

           CloneHelper CloneHelper = new CloneHelper();
           Hashtable drawHashtable = CloneHelper.DeepCloneObject<Hashtable>(hashtable);

           foreach (StockQuote value in drawHashtable.Values)
           {
               DrawRealTimeChart DrawRealTimeChart = new DrawRealTimeChart();
               try
               {
                   Chart chart = DrawRealTimeChart.GetChart(value);
                   if (chart != null)
                   {
                       string picName = string.Format("{0}.png", value.Windcode);
                       string fileName = string.Format("{0}Lib\\{1}", EnvironmentHelper.PhyAppPath, picName);
                       chart.Save(fileName, ChartImageFormat.Jpeg);
                   }
               }
               catch (Exception e)
               {
                   LogHelper.Write(string.Format("生成{0}图片时出错", value.Windcode), e);
               }

               //using(Chart myChart = DrawRealTimeChart.GetChart(value))
               //{
               //    string picName = "DefaultChart.png";
               //    string fileName = string.Format("{0}Picture\\{1}", EnvironmentHelper.PhyAppPath, picName);

               //    //MemoryStream stream = new MemoryStream();
               //    //myChart.Save(stream, ChartImageFormat.Jpeg);
               //    myChart.Save(fileName, ChartImageFormat.Jpeg);

               //    //byte[] mydata = new byte[stream.Length];
               //    //mydata = stream.ToArray();
               //    //stream.Close();

               //    //info.ApplicationSWF = Convert.ToBase64String(mydata);
               //}

           }

       }

       public void DrawAllCharts()
       {
           foreach (var key in hashtable.Keys)
           {
               DrawChart(hashtable[key] as string);
           }
       }

       public List<string> GetAllRegisteredWindCode()
       {
           List<string> listWindCodes = new List<string>();
           foreach (var key in hashtable.Keys)
           {
               listWindCodes.Add( hashtable[key] as string);
           }
           return listWindCodes;
       }

      public void DrawChart(string windcode)
       {
           if (string.IsNullOrEmpty(windcode))
           {
               return;
           }

           if (hashtable.ContainsKey(windcode))
           {               
               StockQuote source = hashtable[windcode] as StockQuote;
               //CloneHelper oCloneHelper = new CloneHelper();
               //StockQuote newStockQuote = oCloneHelper.DeepCloneObject<StockQuote>(source);
               StockQuote newStockQuote = Copy(source);

               DrawRealTimeChart DrawRealTimeChart = new DrawRealTimeChart();
               try
               {
                   using (Chart chart = DrawRealTimeChart.GetChart(newStockQuote))
                   {
                       if (chart != null)//todo 
                       {
                           string picName = string.Format("{0}.png", newStockQuote.Windcode);
                           string fileName = string.Format("{0}Lib\\{1}", EnvironmentHelper.PhyAppPath, picName);
                           if (FileHelper.IsFileExist(fileName))
                           {
                               File.Delete(fileName);
                           }

                           chart.Save(fileName, ChartImageFormat.Jpeg);
                       }

                   }

                   //Chart chart = DrawRealTimeChart.GetChart(newStockQuote);
                   //if (chart != null)
                   //{
                   //    string picName = string.Format("{0}.png", newStockQuote.Windcode);
                   //    string fileName = string.Format("{0}Lib\\{1}", EnvironmentHelper.PhyAppPath, picName);
                   //    chart.Save(fileName, ChartImageFormat.Jpeg);
                   //}
               }
               catch (Exception e)
               {
                   LogHelper.Write(string.Format("生成{0}图片时出错", newStockQuote.Windcode), e);
               }

           }
       }


        ////todo 抽取出公用方法
        //public string ArrCharToString(byte[] src)
        //{
        //    string des = Encoding.Default.GetString(src);
        //    des = des.Trim('\0');
        //    return des;
        //}

        public StockQuote GetData(string windcode)
        {
            if (hashtable.Contains(windcode))
            {
                return hashtable[windcode] as StockQuote;
            }

            return null;
        }

        public StockQuote Copy(StockQuote source)
        {
            StockQuote target = source.Clone();

            lock (source)
            {
                target.QuoteDateList = (from item in source.QuoteDateList
                                        select item).ToList();

                target.QuotePriceList = (from item in source.QuotePriceList
                                         select item).ToList();

                target.QuoteSwingPercentList = (from item in source.QuoteSwingPercentList
                                                select item).ToList();
            }
            return target;
        }

    }
}